#include "app_bluetooth.h"
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include "log/log.h"

static uint8_t bt_buf[128] = {0};
static uint8_t bt_buf_len = 0;
static const uint8_t fix_header[2] = {0xF1, 0xDD};

/**
 * @brief 从bt_buf的头部删除n个字节
 *
 * @param n 要删除的字节数
 */
static void app_bluetooth_deleteFromHead(uint8_t n)
{
    if (n <= bt_buf_len)
    {
        memmove(bt_buf, bt_buf + n, bt_buf_len - n);
        bt_buf_len -= n;
    }
    else
    {
        bt_buf_len = 0;
    }
}

static int app_bluetooth_waitACK(Device *dev)
{
    char buf[4];
    usleep(200000);
    size_t read_len = read(dev->fd, buf, 4);
    if (read_len != 4)
    {
        return -1;
    }
    if (strncmp(buf, "OK\r\n", 4) != 0)
    {
        return -1;
    }
    return 0;
}

int app_bluetooth_stat(Device *dev)
{
    if (write(dev->fd, "AT\r\n", 4) < 0)
    {
        return -1;
    }

    return app_bluetooth_waitACK(dev);
}

int app_bluetooth_reset(Device *dev)
{
    if (write(dev->fd, "AT+RESET\r\n", 10) < 0)
    {
        return -1;
    }

    return app_bluetooth_waitACK(dev);
}

int app_bluetooth_setMaddr(Device *dev, char *maddr)
{
    char buf[32];
    snprintf(buf, 32, "AT+MADDR%s\r\n", maddr);
    if (write(dev->fd, buf, strlen(buf)) < 0)
    {
        return -1;
    }

    return app_bluetooth_waitACK(dev);
}

int app_bluetooth_setNetID(Device *dev, char *netid)
{
    char buf[32];
    snprintf(buf, 32, "AT+NETID%s\r\n", netid);
    if (write(dev->fd, buf, strlen(buf)) < 0)
    {
        return -1;
    }

    return app_bluetooth_waitACK(dev);
}

int app_bluetooth_setBaudrate(Device *dev, Baudrate baudrate)
{
    char buf[16] = "AT+BAUD4\r\n";
    switch (baudrate)
    {
    case BAUD_9600:
        buf[7] = '4';
        break;
    case BAUD_19200:
        buf[7] = '5';
        break;
    case BAUD_38400:
        buf[7] = '6';
        break;
    case BAUD_57600:
        buf[7] = '7';
        break;
    case BAUD_115200:
        buf[7] = '8';
        break;
    default:
        break;
    }
    if (write(dev->fd, buf, strlen(buf)) < 0)
    {
        return -1;
    }

    return app_bluetooth_waitACK(dev);
}

size_t app_bluetooth_postRead(Device *dev, char *data, size_t len)
{
    // 1. 拼接数据帧
    memcpy(bt_buf + bt_buf_len, data, len);
    bt_buf_len += len;

    // 验证数据帧是否完整：1.可能是下游设备发来的数据 2. ACK 3. 其他数据帧（抛弃）
    // 首先验证bt_buf中数据的长度
    if (bt_buf_len < 4)
    {
        // 数据不足，不用处理
        return 0;
    }

    if (memcmp(bt_buf, "OK\r\n", 4) == 0)
    {
        // 数据帧是ACK
        // 处理ACK
        app_bluetooth_deleteFromHead(4);
        return 0;
    }

    if (memcmp(bt_buf, fix_header, 2) == 0)
    {
        // 数据帧为下游设备发来的数据
        if (bt_buf_len < bt_buf[2] + 3)
        {
            // 当前数据帧仍然不完整
            return 0;
        }
        data[0] = TYPE_BT;
        data[1] = 2;
        data[2] = bt_buf[2] - 4;
        memcpy(data + 3, bt_buf + 3, 2);
        memcpy(data + 5, bt_buf + 7, bt_buf[2] - 4);
        app_bluetooth_deleteFromHead(bt_buf[2] + 3);
        return 3 + data[1] + data[2];
    }

    // 其他不需要的数据，尝试寻找“OK”或者 0xF1 0xDD的索引
    size_t i = 0;
    for (i = 0; i < bt_buf_len - 1; i++)
    {
        if (memcmp(bt_buf + i, "OK", 2) == 0 || memcmp(bt_buf + i, fix_header, 2) == 0)
        {
            break;
        }
    }
    app_bluetooth_deleteFromHead(i);
    return 0;
}

size_t app_bluetooth_preWrite(Device *dev, char *data, size_t len)
{
    // data中的数据帧为网关内部的数据帧
    uint8_t output_buf[64] = "AT+MESH";
    if (data[0] != TYPE_BT || data[1] != 2)
    {
        log_warn("invalid data frame type");
        return 0;
    }

    memcpy(output_buf + 8, data + 3, 2);
    memcpy(output_buf + 10, data + 5, data[2]);
    memcpy(output_buf + 10 + data[2], "\r\n", 2);
    uint8_t output_len = 12 + data[2];
    memcpy(data, output_buf, output_len);

    for (size_t i = 0; i < output_len; i++)
    {
        printf("%02x ", data[i]);
    }
    printf("\n");

    return output_len;
}
